/* polyspace<MISRA-C3:1.1:Not a defect:Justify with annotations> */ 
/** 
 * @file         : \\can.c
 * @author       : Liubingqian
 * @brief        : 
 * @
 * @par          : 
 * @Copyright    : Copyright (c) 2023 AOTECAR, All Rights Reserved. 
 */
/*------------------------------------------------------------------------------
            R E V I S I O N   H I S T O R Y                                     
-------------------------------------------------------------------------------
  Date           Version        Author       Description                        
-------------------------------------------------------------------------------
2020.11.17       01.00.00       linmin        Creation                          
------------------------------------------------------------------------------*/
/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2023 Liu bingqian
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "can.h"
#include "header.h"

/**
 * @addtogroup Global_Function
 * @{
 * @brief       : initialize CAN controller
 * @param        {CAN_SFRmap*} CANx:
 * @param        {uint8_t} Bdrt:
 * @param        {uint32_t} MODE:
 * @pre         : None
 * @post        : None
 * @return       {None}
 */
void xInit_CAN(CAN_SFRmap *CANx, uint8_t Bdrt, uint32_t MODE)
{
	CAN_InitTypeDef CAN_InitStructure;
	CAN_Reset(CANx);
	CAN_InitStructure.m_Acceptance = xCAN_ACR;                  
	CAN_InitStructure.m_AcceptanceMask = xCAN_MSK;		        
	CAN_InitStructure.m_WorkSource = CAN_SOURCE_SCLK_DIV_2;     
	CAN_InitStructure.m_BaudRate = 5;					  		
	CAN_InitStructure.m_TimeSeg1 = 14;						   	
	CAN_InitStructure.m_TimeSeg2 = 3;						   	
	CAN_InitStructure.m_BusSample = CAN_BUS_SAMPLE_1_TIME;	   	
	CAN_InitStructure.m_SyncJumpWidth = 1;					   	
	CAN_InitStructure.m_Enable = TRUE;						   	
	CAN_InitStructure.m_Mode = MODE;				           	
	CAN_Configuration(CANx, &CAN_InitStructure);			   	
}

/**
 * @addtogroup Global_Function
 * @{
 * @brief       : initlize CAN interrupt
 * @param        {CAN_SFRmap*} CANx:
 * @pre         : None
 * @post        : None
 * @return       {None}
 */
void xINT_CAN(CAN_SFRmap *CANx)
{
	uint32 delay_i;
    #if HARDWARE_ARBITRATION
	CAN_Set_INT_Enable(CANx, CAN_INT_TRANSMIT | CAN_INT_BUS_ERROR, TRUE);
    #else
	CAN_Set_INT_Enable(CANx, CAN_INT_TRANSMIT | CAN_INT_BUS_ERROR | CAN_INT_ARBITRATION_LOST, TRUE);
    #endif 
	CAN_Set_INT_Enable(CANx, CAN_INT_RECEIVE, TRUE);
	INT_Interrupt_Priority_Config(CAN_INT, 1, 2); 	
	INT_Clear_Interrupt_Flag(CAN_INT); 				
	INT_Interrupt_Enable(CAN_INT, TRUE); 			
}

/**
 * @addtogroup Global_Function
 * @{
 * @brief       : Can hardware transmission function
 * @param        {None}
 * @pre         : None
 * @post        : None
 * @return       {CAN_ErrorT}
 * @retval       {CAN_ErrorT} : CAN_ERROR_NOERROR
 * @retval       {CAN_ErrorT} : CAN_ERROR_BUFFERFULL
 */
CAN_ErrorT CAN_Transmit_DATA(CAN_SFRmap *CANx,
							 uint32_t TargetID,
							 uint8_t *thing,
							 uint8_t lenth,
							 uint32_t MsgType,
							 uint32_t RmtFrm)
{
	CAN_ErrorT x;
	uint8_t i;
	CAN_MessageTypeDef CAN_MessageStructure;		 ///< CAN send data structure
	CAN_MessageStructure.m_FrameFormat = RmtFrm;	 ///< frame format
	CAN_MessageStructure.m_RemoteTransmit = MsgType; ///< remote frame
	if (RmtFrm == CAN_FRAME_FORMAT_SFF)				 ///<
	{
		CAN_MessageStructure.m_StandardID = TargetID; ///< standard frame ID
		CAN_MessageStructure.m_ExtendedID = 0;			         
	}
	else if (RmtFrm == CAN_FRAME_FORMAT_EFF)
	{
		CAN_MessageStructure.m_StandardID = 0;					 
		CAN_MessageStructure.m_ExtendedID = TargetID; ///< extended frame ID
	}
	if (lenth > 8)
	{
		lenth = 8; ///<
	}
	CAN_MessageStructure.m_DataLength = lenth; ///< data length
	for (i = 0; i < lenth; i++)
	{
		CAN_MessageStructure.m_Data[i] = thing[i]; ///< data
	}
	if ((!CAN_Get_Transmit_Status(CANx, CAN_TX_BUFFER_STATUS))) ///< send buffer is  full
	{
		x = CAN_ERROR_BUFFERFULL;
		return x;
	}
	CAN_Transmit_Message_Configuration(CANx, &CAN_MessageStructure); ///< CAN send data configuration , hardware send
    #if HARDWARE_ARBITRATION
        CANx->CTLR = CANx->CTLR | 0x100;    
    #else
	    CANx->CTLR = CANx->CTLR | 0x300;	
    #endif 
	x = CAN_ERROR_NOERROR; ///< send success
	return x;
}